package com.itttq.kb.controller;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.itttq.kb.cmpt.EmailTools;
import com.itttq.kb.model.po.TopicPo;
import com.itttq.kb.model.po.TopicReplyPo;
import com.itttq.kb.model.po.UserPo;
import com.itttq.kb.model.to.PageParamTo;
import com.itttq.kb.model.to.ResultDataTo;
import com.itttq.kb.model.to.ResultTo;
import com.itttq.kb.service.TopicReplyService;
import com.itttq.kb.service.UserService;
import com.itttq.kb.utils.Constants;
import com.itttq.kb.utils.EncryptUtil;

@RestController
@RequestMapping("user")
public class UserController extends GenericController {
	private static final long serialVersionUID = -71983467036276954L;
	@Autowired
	private EmailTools emailTools;
	@Autowired
	private UserService userService;
	@Autowired
	protected TopicReplyService topicReplyService;
	@Autowired
	protected CommonController commonController;
	
	public static Map<String, String> ValidateCode = new HashMap<String, String>();
	/**
	 * 登录
	 * 
	 * @param user
	 * @param request
	 * @return
	 * @Author 迷蝶
	 * @return ModelAndView
	 */
	@RequestMapping("login")
	@ResponseBody
	public ResultDataTo<UserPo> login(UserPo user, HttpServletRequest request) {
		ResultDataTo<UserPo> rt = userService.login(user.getUsername(), user.getPassword());
		rt.setAction("/login.html");
		// 放入session
		if(null != rt && rt.getCode()==ResultTo.SUCCESS) {
			this.setSession(request, Constants.SESSION_USER, rt.getData());
			rt.setAction("/index.html");
		}
		rt.setData(null);
		return rt;
	}
	
	/**
	 * 退出登录
	 * 
	 * @param user
	 * @param request
	 * @Author 迷蝶
	 * @return ResultDataTo<UserPo>
	 */
	@RequestMapping("logout")
	@ResponseBody
	public ModelAndView logout(HttpServletRequest request) {
		ModelAndView mv = new ModelAndView("/index.html");
		this.getSession(request).invalidate();
		return mv;
	}
	
	@RequestMapping("reg")
	@ResponseBody
	public ResultTo reg(UserPo user, String vercode, HttpServletRequest request) {
		ResultTo rt = new ResultTo(ResultTo.FAIL);
		rt.setAction("/reg.html");
		if(StringUtils.isBlank(user.getUsername()) || StringUtils.isBlank(user.getPassword())
				|| StringUtils.isBlank(vercode)) {
			rt.setMsg("用户名、密码或验证码不能为空！");
			return rt;
		}
		// 判断验证码
		Object code = this.getSession(request, Constants.SESSION_CODE_REG);
		if(null == code || !vercode.equals(code.toString())) {
			rt.setMsg("验证码无效！");
			return rt;
		}
		// 验证码失效
		this.getSession(request).removeAttribute(Constants.SESSION_CODE_REG);
		try {
			// 判断是否存在
			UserPo u = new UserPo();
			u.setUsername(user.getUsername());
			int i = userService.getUserCount(u);
			if(i == 0) {
				userService.addUser(user);
				rt.setCode(ResultTo.SUCCESS);
				rt.setMsg("注册成功！正在跳转到登录页面…");
				rt.setAction("/login.html");
			} else {
				rt.setMsg("用户名已经注册！");
			}
		} catch (NoSuchAlgorithmException e) {
			rt.setMsg("发生错误！");
			e.printStackTrace();
		}
		return rt;
	}
	
	@RequestMapping("vc")
	@ResponseBody
	public ResultTo reg(String email, HttpServletRequest request) {
		ResultTo rt = new ResultTo(ResultTo.FAIL);
		rt.setAction("/reg.html");
		if(StringUtils.isBlank(email)) {
			rt.setMsg("邮箱不能为空！");
			return rt;
		}
		try {
			String code = Constants.genRandomNum(6);
			emailTools.sendMail(email, "熊猫知识库的注册验证码", "您在熊猫知识库的注册验证为：" + code + "，有效期为30分钟。");
			this.setSession(request, Constants.SESSION_CODE_REG, code);
			rt.setCode(ResultTo.SUCCESS);
			rt.setMsg("注册码已发送，请登录邮箱查看。");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rt;
	}
	
	/**
	 * 用户主页信息，
	 * 
	 * @param request
	 * @return
	 * @Author 迷蝶
	 * @return ModelAndView
	 */
	@RequestMapping("/{uid}.html")
	public ModelAndView topicHome(@PathVariable("uid")Integer uid, HttpServletRequest request) {
		ModelAndView mv = new ModelAndView("/user/home");
		// 获取当前登录的用户信息
		mv.addObject("user", getUserBySession(request));
		// 获取用户信息
		mv.addObject("u", userService.getUser(uid));
		// 获取用户发表主题
		TopicPo topic = new TopicPo();
		topic.setCreatorId(uid);
		mv.addObject("topics", topicService.getTopics(topic, this.getPageParam(10)));
		// 获取用户回复
		TopicReplyPo topicReply = new TopicReplyPo();
		topicReply.setCreatorId(uid+0l);
		mv.addObject("replies", topicReplyService.getTopicReplys(topicReply, this.getPageParam(5)));
		return mv;
	}
	
	/**
	 * 用户管理页信息，
	 * 
	 * @param request
	 * @return
	 * @Author 迷蝶
	 * @return ModelAndView
	 */
	@RequestMapping("/index.html")
	public ModelAndView topicIndex(HttpServletRequest request) {
		ModelAndView mv = new ModelAndView("/user/index");
		UserPo user = getUserBySession(request);
		// 获取当前登录的用户信息
		mv.addObject("user", user);
		// 获取用户发表主题
		TopicPo topic = new TopicPo();
		topic.setCreatorId(user.getId());
		PageParamTo topicPpt = this.getPageParam(10);
		topicPpt.setCount(topicService.getTopicCount(topic));
		mv.addObject("topicPpt", topicPpt);
		mv.addObject("topics", topicService.getTopics(topic, topicPpt));
		// 获取用户回复
		TopicReplyPo topicReply = new TopicReplyPo();
		topicReply.setCreatorId(user.getId()+0l);
		PageParamTo replyPpt = this.getPageParam(10);
		replyPpt.setCount(topicReplyService.getTopicReplyCount(topicReply));
		mv.addObject("repliePpt", replyPpt);
		mv.addObject("replies", topicReplyService.getTopicReplys(topicReply, this.getPageParam(5)));
		return mv;
	}
	
	@RequestMapping("set.html")
	public ModelAndView set(HttpServletRequest request) {
		ModelAndView mv = new ModelAndView("/user/set");
		// 获取当前登录的用户信息
		mv.addObject("user", getUserBySession(request));
		return mv;
	}
	
	/**
	 * 修改密码
	 * 
	 * @param request
	 * @return
	 * @Author 迷蝶
	 * @return ModelAndView
	 */
	@RequestMapping("forget.html")
	public ModelAndView forget(String email, String vercode, HttpServletRequest request) {
		ModelAndView mv = new ModelAndView("/forget");
		// 判断邮件是否存在
		UserPo user = new UserPo();
		user.setUsername(email);
		List<UserPo> users= userService.getUsers(user, this.getPageParam(2));
		if(null == user || users.size() == 0) {
			mv.addObject("msg", "用户不存在！请检测您的邮箱是否填写正确！");
			mv.addObject("email", email);
			return mv;
		}
		Object c = this.getSession(request, Constants.SESSION_CODE_GETPWD);
		if(null == vercode || null == c || !vercode.equalsIgnoreCase(String.valueOf(c))) {
			mv.addObject("msg", "验证码不正确！");
			mv.addObject("email", email);
			return mv;
		}
		try {
			String code = Constants.genRandomNum(12);
			ValidateCode.put(email, code);
			ValidateCode.put(email+"_id", String.valueOf(users.get(0).getId()));
			// 发送邮件带连接
			emailTools.sendMail(email, "熊猫知识库的密码重置链接", "您的重置密码链接为：<a href=\"http://ask.xiongmao1718.com/user/resetPwd.html?e="
			+email+"&c=" +code + "\">重置密码</a>。如不能正常显示，可以复制下面的链接在浏览器打开：<br><br>"
			+ "http://ask.xiongmao1718.com/user/resetPwd.html?e="+email+"&c="+code);
			mv.addObject("mailAddress", email);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mv;
	}
	
	/**
	 * 邮件跳转到重置密码连接
	 * 
	 * @param request
	 * @return
	 * @Author 迷蝶
	 * @return ModelAndView
	 */
	@RequestMapping("resetPwd.html")
	public ModelAndView resetPwd(String c, String e, HttpServletRequest request) {
		ModelAndView mv = new ModelAndView("/forget");
		// 判断是否验证码正确
		String code = ValidateCode.get(e);
		if(StringUtils.isNotBlank(code) && c.equals(code)) {
			mv.addObject("validate", "true");
			mv.addObject("email", e);
			ValidateCode.put(e, "true");
		} else {
			mv.addObject("validate", "false");
		}
		return mv;
	}
	
	/**
	 * 修改用户密码
	 * 
	 * @param request
	 * @return
	 * @Author 迷蝶
	 * @return ModelAndView
	 */
	@RequestMapping("/resetPassword.html")
	public ModelAndView resetPassword(String email, String password) {
		ModelAndView mv = new ModelAndView("/forget");
		mv.addObject("validate", true);
		if (StringUtils.isBlank(password) || StringUtils.isBlank(email)) {
			mv.addObject("msg", "传入邮箱和新密码不能为空！");
			return mv;
		}
		// 验证此邮箱是不是经过邮箱验证通过
		String vc = ValidateCode.get(email);
		if(null == vc || !vc.equals("true")) {
			mv.addObject("validate", false);
			return mv;
		}
		
		try {
			// 重新生成slat并加密
			userService.modifyPwd(password, Integer.valueOf(ValidateCode.get(email+"_id")));
			mv.setViewName("/login");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return mv;
	}
	
	/**
	 * 修改用户密码
	 * 
	 * @param request
	 * @return
	 * @Author 迷蝶
	 * @return ModelAndView
	 */
	@RequestMapping("/repass")
	public ResultTo modifyPwd(String nowpass, String pass, HttpServletRequest request) {
		ResultTo rt = new ResultTo(ResultTo.FAIL);
		if (StringUtils.isBlank(nowpass) || StringUtils.isBlank(pass)) {
			rt.setCode(ResultTo.PARAM_INCORRECT);
			rt.setMsg("密码或新密码不能为空！");
			return rt;
		}
		
		UserPo user = getUserBySession(request);
		if(null == user) {
			rt.setCode(ResultTo.SESS_TIMEOUT);
			rt.setMsg("登录超时！");
			return rt;
		}
		// 判断输入密码和原密码一致
		try {
			if(EncryptUtil.getPassword(nowpass, user.getSalt()).equals(user.getPassword())) {
				// 重新生成slat并加密
				userService.modifyPwd(pass, user.getId());
				user.setPassword(pass);
				 this.setSession(request, Constants.SESSION_USER, user);
			} else {
				rt.setMsg("原密码错误！");
			}
		} catch (NoSuchAlgorithmException e) {
			rt.setMsg("发生错误！");
			e.printStackTrace();
		}
		return rt;
	}
	
	/**
	 * 修改用户头像
	 * 
	 * @param request
	 * @Author 迷蝶
	 * @return ModelAndView
	 */
	@RequestMapping("/modifyAvatar")
	public ResultTo modifyAvatar(MultipartFile file, HttpServletRequest request) {
		ResultTo rt = new ResultTo(ResultTo.FAIL);
		try {
			rt = commonController.uploadImage(1, file);
			if(rt.getCode() == ResultTo.SUCCESS) {
				// 判断上传成功后，则更新用户头像信息
				UserPo user = getUserBySession(request);
				user.setAvatar(rt.getMsg());
				userService.updateUser(user);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return rt;
	}
}
